/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package im.clusterhead;

import im.general.AbstractListenBehaviour;
import im.general.Config;
import im.messages.ClusteringMsgPayload;
import im.node.MobileNodeInfo;
import jade.core.AID;
import jade.core.ContainerID;

import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author Gnaskky
 */
public class ClusterJoinServerBehaviour extends AbstractListenBehaviour {

    private ClusterHeadAgent ch;

    ClusterJoinServerBehaviour(ClusterHeadAgent ch) {
        this.ch = ch;
        ACLMessage wrap_msg = new ACLMessage( ACLMessage.REQUEST );
        wrap_msg.addUserDefinedParameter( Config.IM_MSG_TYPE, Config.SRVC_JOIN_REQ_MSG);
        this.mt = MessageTemplate.MatchCustom(wrap_msg, true);
    }

    @Override
    protected void handleMessage(ACLMessage in_msg) {
        try {
            /* VEDERE:
             * gestione DB cluster
             * status handling
             * */
            /*
            add_to_local_db;
            ES.notify_join(isNewJoin);
            get_ack(ES);
            send_ack(CLI);
            if(meetClusterizeConditions())
            clusterize();
             * */
            String mn = in_msg.getSender().getName();

            if( Config.TRACE_LVL > Config.EXTREME_TR_LVL )
                System.out.println("[ClusterJoinServerBe]\tSRVC_JOIN_REQ_MSG from:\t  "
                        + mn.split("@")[0] + "\t" + ch.getLocalName());

            //if not yet in CH DB's
            if( ch.getNodeInfo(mn) == null ) {
                //MobileNodeInfo mn_info = new MobileNodeInfo(mn, ch.getName(), null, in_msg.getSender());
                MobileNodeInfo mn_info = (MobileNodeInfo) in_msg.getContentObject();
                mn_info.setCh_name(ch.getLocalName());
                ch.addNode(mn, mn_info);

                System.out.println( "TEST ->>>>>>>>>>>>>>>>>>>>>>> " + mn_info.getResourceStatus().getChargeReminderMah() );

                // ES.notify_join;
                //ClusteringMsgPayload pl = new ClusteringMsgPayload(mn_info, this.ch.getStatus());
                ACLMessage jntfy_msg = new ACLMessage(ACLMessage.CONFIRM);
                jntfy_msg.addUserDefinedParameter(Config.IM_MSG_TYPE, Config.SRVC_JOIN_NOTIFY_MSG);
                jntfy_msg.addReceiver(new AID(Config.EVENT_SERVICE_NAME, AID.ISLOCALNAME));
                //jntfy_msg.setContentObject(mn_info);
                jntfy_msg.setContentObject(new ClusteringMsgPayload(mn_info, this.ch.getStatus()));
                ch.send(jntfy_msg);

                // Checking Clusterize Conditions
                if (ch.checkClusterizeConditions()) {
                    this.clusterize();
                }
            }
            
        } catch (Exception ex) {
            Logger.getLogger(ClusterJoinServerBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    protected void clusterize() {
        try {
            // SELECTING a new Hosting node for CH
            MobileNodeInfo new_ch = ch.selectNodeToMakeCH();
            
            // Sending CH agent
            ch.addCloneCount();
            ch.setClonedMNguestAgent(new_ch.getNode_name());
            String new_ch_name = ch.getLocalName() + ch.getCloneCount();
            
            ch.doClone(new ContainerID(new_ch.getContainerName(), null), new_ch_name);

            // Notify new CH to ES
            //TODO fix info
            ACLMessage ntfy_ch_msg = new ACLMessage(ACLMessage.PROPOSE);
            ntfy_ch_msg.addUserDefinedParameter(Config.IM_MSG_TYPE, Config.NEW_CH_NOTIFY_MSG);
            ntfy_ch_msg.addUserDefinedParameter(Config.NEW_CH_NAME, new_ch_name);
            ntfy_ch_msg.addUserDefinedParameter(Config.NEW_CH_CONTAINER, new_ch.getContainerName());
            ntfy_ch_msg.addReceiver(new AID(Config.EVENT_SERVICE_NAME, AID.ISLOCALNAME));
            ntfy_ch_msg.setContentObject(new ClusterHeadInfo(new_ch.getNode_name()));
            ch.send(ntfy_ch_msg);

            //now the selected node is a CH so remove it :)
            ch.removeNode(new_ch.getNode_name());

            /*
            // Advertise cluster MNs
            ACLMessage adv_ch_msg = new ACLMessage(ACLMessage.PROPAGATE);
            adv_ch_msg.addUserDefinedParameter(Config.IM_MSG_TYPE, Config.NEW_CH_ADVERTISE_MSG);
            adv_ch_msg.addUserDefinedParameter(Config.NEW_CH_NAME, new_ch_name);

            Enumeration nod = ch.getNodeNames();

            String mn_n;

            // switch if-while
            while(nod.hasMoreElements()) {
                mn_n = (String)nod.nextElement();
                //System.out.println("push to: " + mn_n);
                adv_ch_msg.addReceiver(new AID(mn_n, AID.ISGUID));
            }

            ch.send(adv_ch_msg);
             * */
            
        } catch (Exception ex) {
            Logger.getLogger(ClusterJoinServerBehaviour.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }

    }
    
}
